package com.zhuo.common.service;

import com.zhuo.common.domain.storage.UploadOptions;
import com.zhuo.common.domain.storage.UploadResult;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.InputStream;

/**
 * 通用文件存储服务接口
 *
 * <p>该接口抽象了对象存储（Object Storage）的常见操作，
 * 旨在为不同厂商（如腾讯 COS、阿里 OSS、MinIO、七牛云、Amazon S3 等）
 * 提供统一、可扩展的文件上传与管理能力。</p>
 * 包括path\File\MultipartFile\InputStream 等上传能力
 *
 * @author xxxzsh
 * @since 1.0.1
 */
public interface StorageService {

    /* ====================== Path 上传 ====================== */

    UploadResult upload(String path);

    /**
     * 上传文件到指定虚拟文件夹。
     *
     * @param path   本地文件路径
     * @param folder 虚拟文件夹（即 key 前缀，例如 "avatar/"）
     * @return 上传结果
     */
    UploadResult upload(String path, String folder);

    /**
     * 使用高级上传配置上传文件。
     *
     * @param path          本地文件路径
     * @param uploadOptions 上传配置
     * @return 上传结果
     */
    UploadResult upload(String path, UploadOptions uploadOptions);

    /* ====================== File 上传 ====================== */

    UploadResult upload(File file);

    /**
     * 上传文件到指定文件夹。
     *
     * @param file   Java File 对象
     * @param folder 上传文件夹（即 key 前缀）
     * @return 上传结果
     */
    UploadResult upload(File file, String folder);

    /**
     * 使用高级上传配置上传文件。
     *
     * @param file          Java File 对象
     * @param uploadOptions 上传配置（可指定 folder、fileName、是否添加日期路径等）
     * @return 上传结果
     */
    UploadResult upload(File file, UploadOptions uploadOptions);

    /* ====================== MultipartFile 上传 ====================== */

    UploadResult upload(MultipartFile file);

    UploadResult upload(MultipartFile file, String folder);

    /**
     * 使用高级上传配置上传文件。
     *
     * @param file          Spring-MultipartFile 对象
     * @param uploadOptions 上传配置（可指定 folder、fileName、是否添加日期路径等）
     * @return 上传结果
     */
    UploadResult upload(MultipartFile file, UploadOptions uploadOptions);

    /* ====================== InputStream 上传 ====================== */

    UploadResult upload(InputStream inputStream, String fileName);

    /**
     * 上传输入流到指定虚拟文件夹并指定文件名。
     *
     * @param inputStream 输入流
     * @param folder      虚拟文件夹 / key 前缀
     * @param fileName    文件名（不含 folder）
     * @return 上传结果
     */
    UploadResult upload(InputStream inputStream, String folder, String fileName);

    /**
     * 上传输入流到指定虚拟文件夹并指定文件名。
     *
     * @param inputStream   输入流
     * @param uploadOptions 上传配置（可指定 folder、fileName、是否添加日期路径等）
     * @return 上传结果
     */
    UploadResult upload(InputStream inputStream, UploadOptions uploadOptions);

    // =========================================== 其它方法 ===========================================

    /**
     * 删除文件
     */
    boolean delete(String key);

    /**
     * 获取文件访问 URL
     */
    String getUrl(String key);

    boolean doesObjectExist(String key);
}
